神经网络的前向传播和反向传播原理及python实现

您所在的位置:网站首页 神经网络 反馈 神经网络的前向传播和反向传播原理及python实现

神经网络的前向传播和反向传播原理及python实现

2024-07-17 17:17| 来源: 网络整理| 查看: 265

神经网络的前向传播和反向传播 总述正文开始初始化 Step 1 前向传播1.输入层---->隐含层:2.隐含层---->输出层: Step 2 反向传播1.计算总误差2.隐含层---->输出层的权值更新:3.隐含层---->隐含层的权值更新: 完整python代码

总述

神经网络 这是典型的三层神经网络的基本构成 Layer L1是输入层,Layer L2是隐含层,Layer L3是隐含层 我们现在手里有一堆数据{x1,x2,x3,…,xn},输出也是一堆数据{y1,y2,y3,…,yn},现在要他们在隐含层做某种变换,让你把数据灌进去后得到你期望的输出。 本文直接举一个例子,带入数值演示反向传播法的过程,并会使用python代码表达

正文开始

假设,你有这样一个网络层: 神经网络图 第一层是输入层,包含两个神经元i1,i2,和截距项b1; 第二层是隐含层,包含两个神经元h1,h2和截距项b2; 第三层是输出o1,o2,每条线上标的wi是层与层之间连接的权重,激活函数我们默认为sigmoid函数。

初始化

现在对他们赋上初值,如下图: 神经网络初始化 其中 输入数据 i1=0.05,i2=0.10; 输出数据 o1=0.01,o2=0.99; 初始权重 w1=0.15,w2=0.20,w3=0.25,w4=0.30; w5=0.40,w6=0.45,w7=0.50,w8=0.55 目标:给出输入数据i1,i2(0.05和0.10),使输出尽可能与原始输出o1,o2(0.01和0.99)接近。

#初始化权重 weights = np.array([[[0.15, 0.20], [0.25, 0.30]], [[0.40, 0.45], [0.50, 0.55]]]) # 输入数据 l0 = np.array([[0.05], [0.10]]) #偏置 bias = np.array([[.35],[0.60]]) #真实值 y = np.array([[0.01],[0.99]]) #学习率 i=0.5 Step 1 前向传播 1.输入层---->隐含层:

计算神经元h1的输入加权和: 在这里插入图片描述 神经元h1的输出o1:(此处用到激活函数为sigmoid函数): 在这里插入图片描述 同理,可计算出神经元h2的输出o2: 在这里插入图片描述

#前向传播 #输入层---->隐含层 temp1 = np.dot(weights[0], l0) +bias[0] l1 = 1 / (1 + np.exp(-temp1)) print("l1",l1) l1 [[0.59326999] [0.59688438]] 2.隐含层---->输出层:

计算输出层神经元o1和o2的值: 在这里插入图片描述 这样前向传播的过程就结束了,我们得到输出值为[0.75136079 , 0.772928465]。 这与实际值[0.01 , 0.99]相差还很远,现在我们对误差进行反向传播,更新权值,重新计算输出。

#隐含层---->输出层: temp2 = np.dot(weights[1], l1) +bias[1] l2 = 1 / (1 + np.exp(-temp2)) print("l2",l2) l2 [[0.75136507] [0.77292847]] Step 2 反向传播 1.计算总误差

总误差:(square error) 在这里插入图片描述 但是有两个输出,所以分别计算o1和o2的误差,总误差为两者之和: 在这里插入图片描述 在这里插入图片描述 在这里插入图片描述

#反向传播 Error = 1 / 2.0 * (y-l2)**2 print("Error",Error) TotalE = np.sum(Error) print("TotalE",TotalE) Error [[0.27481108] [0.02356003]] TotalE 0.2983711087600027 2.隐含层---->输出层的权值更新:

以权重参数w5为例,如果我们想知道w5对整体误差产生了多少影响,可以用整体误差对w5求偏导求出:(链式法则) 在这里插入图片描述 下面的图可以更直观的看清楚误差是怎样反向传播的: 在这里插入图片描述 现在我们来分别计算每个式子的值: 计算: 在这里插入图片描述 在这里插入图片描述

计算 在这里插入图片描述 在这里插入图片描述 (这一步实际上就是对sigmoid函数求导,比较简单,可以自己推导一下)

计算 在这里插入图片描述 在这里插入图片描述 最后三者相乘: 在这里插入图片描述 这样我们就计算出整体误差E(total)对w5的偏导值。 回过头来再看看上面的公式,我们发现: 在这里插入图片描述 为了表达方便,用 在这里插入图片描述 来表示输出层的误差: 在这里插入图片描述 因此,整体误差E(total)对w5的偏导公式可以写成: 在这里插入图片描述 如果输出层误差计为负的话,也可以写成: 在这里插入图片描述 最后我们来更新w5的值: 在这里插入图片描述 (其中, 在这里插入图片描述 是学习速率,这里我们取0.5)

同理,可更新w6,w7,w8: 在这里插入图片描述

#隐含层---->输出层的权值更新 alphaE1 = - (y - l2) alphaE2 = l2 * (1-l2) alphaE3 = l1 print("alphaE1",alphaE1) print("alphaE2",alphaE2) print("alphaE3",alphaE3) alphaE = alphaE1 * alphaE2 * alphaE3 print("alphaE",alphaE) #更新权重 weightsT1 = weights[1] - i * alphaE print("weightsT1",weightsT1) alphaE1 [[ 0.74136507] [-0.21707153]] alphaE2 [[0.1868156 ] [0.17551005]] alphaE3 [[0.59326999] [0.59688438]] alphaE [[ 0.08216704] [-0.02274024]] weightsT1 [[0.35891648 0.40891648] [0.51137012 0.56137012]] 3.隐含层---->隐含层的权值更新:

方法其实与上面说的差不多,但是有个地方需要变一下,在上文计算总误差对w5的偏导时,是从out(o1)---->net(o1)---->w5,但是在隐含层之间的权值更新时,是out(h1)---->net(h1)---->w1,而out(h1)会接受E(o1)和E(o2)两个地方传来的误差,所以这个地方两个都要计算。  在这里插入图片描述  计算 在这里插入图片描述 在这里插入图片描述 先计算 在这里插入图片描述 在这里插入图片描述 在这里插入图片描述 在这里插入图片描述 在这里插入图片描述 在这里插入图片描述 同理,计算出: 在这里插入图片描述 再计算 在这里插入图片描述 在这里插入图片描述 再计算 在这里插入图片描述 在这里插入图片描述 最后,三者相乘: 在这里插入图片描述 为了简化公式,用sigma(h1)表示隐含层单元h1的误差: 在这里插入图片描述 最后,更新w1的权值: 在这里插入图片描述 同理,额可更新w2,w3,w4的权值: 在这里插入图片描述 这样误差反向传播法就完成了,最后我们再把更新的权值重新计算,不停地迭代

#隐含层---->隐含层的权值更新: alphaE41 = alphaE1 * alphaE2 alphaE42 = weights[1] alphaE4 = alphaE41 * alphaE42 print("alphaE41",alphaE41) print("alphaE42",alphaE42) print("alphaE4",alphaE4) alphaE4s = alphaE4[0] + alphaE4[1] print("alphaE4s",alphaE4s) alphaE5 = l1 * (1 - l1) print("alphaE5",alphaE5) alphaE6 = l0 print("alphaE6",alphaE6) alphaEE = alphaE4s * alphaE5 * alphaE6 print("alphaEE",alphaEE) #更新权重 weightsT2 = weights[0] - i * alphaEE print("weightsT2",weightsT2) alphaE41 [[ 0.13849856] [-0.03809824]] alphaE42 [[0.4 0.45] [0.5 0.55]] alphaE4 [[ 0.05539942 0.06232435] [-0.01904912 -0.02095403]] alphaE4s [0.03635031 0.04137032] alphaE5 [[0.24130071] [0.24061342]] alphaE6 [[0.05] [0.1 ]] alphaEE [[0.00043857 0.00049913] [0.00087464 0.00099543]] weightsT2 [[0.14978072 0.19975043] [0.24956268 0.29950229]] 完整python代码 import numpy as np #初始化权重 weights = np.array([[[0.15, 0.20], [0.25, 0.30]], [[0.40, 0.45], [0.50, 0.55]]]) # 输入数据 l0 = np.array([[0.05], [0.10]]) #偏置 bias = np.array([[.35],[0.60]]) #真实值 y = np.array([[0.01],[0.99]]) #学习率 i=0.5 for j in range(100): #前向传播 #输入层---->隐含层 temp1 = np.dot(weights[0], l0) +bias[0] l1 = 1 / (1 + np.exp(-temp1)) print("l1",l1) #隐含层---->输出层: temp2 = np.dot(weights[1], l1) +bias[1] l2 = 1 / (1 + np.exp(-temp2)) print("l2",l2) #反向传播 Error = 1 / 2.0 * (y-l2)**2 print("Error",Error) #隐含层---->输出层的权值更新 TotalE = np.sum(Error) print("TotalE",TotalE) alphaE1 = - (y - l2) alphaE2 = l2 * (1-l2) alphaE3 = l1 print("alphaE1",alphaE1) print("alphaE2",alphaE2) print("alphaE3",alphaE3) alphaE = alphaE1 * alphaE2 * alphaE3 print("alphaE",alphaE) #更新权重 weightsT1 = weights[1] - i * alphaE print("weightsT1",weightsT1) #隐含层---->隐含层的权值更新: alphaE41 = alphaE1 * alphaE2 alphaE42 = weights[1] alphaE4 = alphaE41 * alphaE42 print("alphaE41",alphaE41) print("alphaE42",alphaE42) print("alphaE4",alphaE4) alphaE4s = alphaE4[0] + alphaE4[1] print("alphaE4s",alphaE4s) alphaE5 = l1 * (1 - l1) print("alphaE5",alphaE5) alphaE6 = l0 print("alphaE6",alphaE6) alphaEE = alphaE4s * alphaE5 * alphaE6 print("alphaEE",alphaEE) #更新权重 weightsT2 = weights[0] - i * alphaEE print("weightsT2",weightsT2) weights[0] = weightsT2 weights[1] = weightsT1 print(Error)

最后的误差,已经变得很小了

[[0.01405175] [0.00634091]]

参考文档



【本文地址】


今日新闻


推荐新闻


    CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3